package com.sangmo.fts.process.factoring.model;

import com.sangmo.boot.framework.data.entity.general.SoftDeleteEntity;
import com.sangmo.boot.framework.data.json.meta.ExtView;
import com.sangmo.boot.framework.data.json.meta.Formula;
import com.sangmo.boot.framework.data.json.meta.One;
import com.sangmo.boot.framework.plugin.dataview.def.meta.DataField;
import com.sangmo.boot.framework.plugin.dataview.def.meta.DataView;
import com.sangmo.fts.basic.model.Company;
import com.sangmo.fts.basic.validation.SellerComValidator;
import com.sangmo.fts.common.IConstants;
import com.sangmo.fts.process.factoring.calculator.FfLoanRepaymentAmountCalculator;
import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.SQLDeleteAll;
import org.hibernate.annotations.Where;

import javax.persistence.Entity;
import javax.persistence.Table;
import java.math.BigDecimal;
import java.util.Date;

@Entity
@Table(name = "ff_loan")
@DataView
@ExtView
@Formula(value = "repaymentAmount", calc = FfLoanRepaymentAmountCalculator.class, groups = {"FfLoan.search","FfLoan.detail"})
@SQLDelete(
        sql = "UPDATE #{entityName} SET deleted = CURRENT_TIMESTAMP WHERE id = ?"
)
@SQLDeleteAll(
        sql = "UPDATE #{entityName} SET deleted = CURRENT_TIMESTAMP WHERE id = ?"
)
@Where(
        clause = "deleted = 0"
)
public class FfLoan extends SoftDeleteEntity {

    @DataField(value = IConstants.DATA_TYPE.LONG, required = true, index = true)
    private Long trainingId;

    @DataField(value = IConstants.DATA_TYPE.STRING_10,required = true, index = true, unique = true)
    private String applyCode;

    @DataField(value = IConstants.DATA_TYPE.STRING_10, index = true)
    private String acceptCode;

    @DataField(value = IConstants.DATA_TYPE.STRING_10, index = true)
    private String code;

    @One(value = "applyCompany", target = Company.class, fieldset = {"id", "name","manager","phone"})
    @DataField(value = IConstants.DATA_TYPE.LONG, required = true, index = true, validators = SellerComValidator.class)
    private Long applyId;

    @One(value = "waybill", target = FfWaybill.class, fieldset = {"id", "code"}, groups = {"FfLoan.search","FfLoan.detail"})
    @DataField(value = IConstants.DATA_TYPE.LONG, required = true, index = true)
    private Long waybillId;

    @One(value = "contract", target = FfContract.class, fieldset = {"id","code"}, groups = {"FfLoan.search","FfLoan.detail","FfLoan.selection"})
    @DataField(value = IConstants.DATA_TYPE.LONG, required = true)
    private Long contractId;

    @DataField(value = IConstants.DATA_TYPE.DECIMAL_POSITIVE_MONEY, required = true)
    private BigDecimal contractAmount;

    @DataField(value = IConstants.DATA_TYPE.DECIMAL_POSITIVE_MONEY, required = true)
    private BigDecimal receivableAmount;

    @One(value = "subDebtorCompany", target = Company.class, fieldset = {"id","name","manager","phone"},groups = {"default","FfFactoringContract.selection"})
    @DataField(value = IConstants.DATA_TYPE.LONG, required = true)
    private Long subDebtor;

    @One(value = "bank", target = Company.class, fieldset = {"id","name"})
    @DataField(value = IConstants.DATA_TYPE.LONG, required = true)
    private Long bankId;

    private BigDecimal amount;

    private Date startTime;

    @DataField(index = true)
    private Date endTime;

    @DataField(value = IConstants.CSF_LOAN_DATA_TYPE.LOAN_DURATION, required = true)
    private String duration;

    private BigDecimal rate;

    @DataField(value = IConstants.CSF_LOAN_DATA_TYPE.LOAN_STATE, required = true, index = true)
    private String state = States.ACCEPTING;

    private BigDecimal approvedAmount;

    private String issueState;

    @DataField(index = true)
    private boolean settled;

    public Long getTrainingId() {
        return trainingId;
    }

    public void setTrainingId(Long trainingId) {
        this.trainingId = trainingId;
    }

    public String getApplyCode() {
        return applyCode;
    }

    public void setApplyCode(String applyCode) {
        this.applyCode = applyCode;
    }

    public String getAcceptCode() {
        return acceptCode;
    }

    public void setAcceptCode(String acceptCode) {
        this.acceptCode = acceptCode;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public Long getApplyId() {
        return applyId;
    }

    public void setApplyId(Long applyId) {
        this.applyId = applyId;
    }

    public Long getWaybillId() {
        return waybillId;
    }

    public void setWaybillId(Long waybillId) {
        this.waybillId = waybillId;
    }

    public Long getContractId() {
        return contractId;
    }

    public void setContractId(Long contractId) {
        this.contractId = contractId;
    }

    public BigDecimal getContractAmount() {
        return contractAmount;
    }

    public void setContractAmount(BigDecimal contractAmount) {
        this.contractAmount = contractAmount;
    }

    public BigDecimal getReceivableAmount() {
        return receivableAmount;
    }

    public void setReceivableAmount(BigDecimal receivableAmount) {
        this.receivableAmount = receivableAmount;
    }

    public Long getSubDebtor() {
        return subDebtor;
    }

    public void setSubDebtor(Long subDebtor) {
        this.subDebtor = subDebtor;
    }

    public Long getBankId() {
        return bankId;
    }

    public void setBankId(Long bankId) {
        this.bankId = bankId;
    }

    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    public BigDecimal getAmount() {
        return amount;
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public String getDuration() {
        return duration;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public BigDecimal getRate() {
        return rate;
    }

    public void setRate(BigDecimal rate) {
        this.rate = rate;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getIssueState() {
        return issueState;
    }

    public void setIssueState(String issueState) {
        this.issueState = issueState;
    }

    public BigDecimal getApprovedAmount() {
        return approvedAmount;
    }

    public void setApprovedAmount(BigDecimal approvedAmount) {
        this.approvedAmount = approvedAmount;
    }

    public boolean isSettled() {
        return settled;
    }

    public void setSettled(boolean settled) {
        this.settled = settled;
    }

    public interface Duration {
        String ONE_MONTH = "ONE_MONTH"; //1个月
        String THREE_MONTH = "THREE_MONTH"; //3个月
        String SIX_MONTH = "SIX_MONTH"; //6个月
    }

    public interface States {
        String ACCEPTING = "ACCEPTING"; //待受理
        String PENDING = "PENDING"; //待审核
        String CONFIRMED = "CONFIRMED"; //审核通过/待放款
        String REJECTED = "REJECTED"; //已驳回
    }

    public interface IssueStates {
        String PENDING = "PENDING";
        String COMPLETED = "COMPLETED";
    }

    public interface IFfLoanRepaymentAmountCalculator{
    }
}
